package com.lengyu.iottransfer.gateway.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.lengyu.iottransfer.gateway.common.ByteUtils;
import com.lengyu.iottransfer.gateway.common.CommonUtils;
import com.lengyu.iottransfer.gateway.config.MqttSendGateway;
import com.lengyu.iottransfer.gateway.dto.MqttDeviceCurrentDto;
import com.lengyu.iottransfer.gateway.entity.DeviceTransfer;
import com.lengyu.iottransfer.gateway.redis.RedisUtils;
import com.lengyu.iottransfer.gateway.service.IDeviceTransferService;
import io.lettuce.core.StrAlgoArgs;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.concurrent.TimeUnit;

/**
 * 铁建工科蒸汽表协议解析
 */
@Service
public class ZhengqiF2001XTransferService {
    private static final Logger logger = LoggerFactory.getLogger(ZhengqiF2001XTransferService.class);
    @Resource
    private MqttSendGateway mqttSendGateway;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    IDeviceTransferService deviceTransferService;

    private static String DEVICE_TYPE = "F2001XA3L1C4R2PWAL1VAC";


    //    @Async // 声明异步方法
    public void decodeData(byte[] payLoad, String topic) {
        String code = topic.split("/")[2];

        String hexStr = redisUtils.get(code);
        byte[] totalByteArray;
        if (StringUtils.isNotBlank(hexStr)) {
            byte[] lastByteArray = ByteUtils.hexStrToByteArray(hexStr);
            totalByteArray = new byte[payLoad.length + lastByteArray.length];
            System.arraycopy(lastByteArray,0,totalByteArray,0,lastByteArray.length);
            System.arraycopy(payLoad,0,totalByteArray,lastByteArray.length,payLoad.length);
        } else {
            totalByteArray = new byte[payLoad.length];
            System.arraycopy(payLoad,0,totalByteArray,0,payLoad.length);
        }

        int byte1 = totalByteArray[0] & 0xFF;
        int byte2 = totalByteArray[1] & 0xFF;
        int byteCount = totalByteArray[2] & 0xFF;
        if (byte1 == 1 && byte2 == 3) {
            if (byteCount + 5 == totalByteArray.length) {
                //完整数据开始处理
                procDecode(totalByteArray,code);

            } else {
                logger.info("不完整数据，先存储:"  + ByteUtils.byteArrayToHexString(totalByteArray));
                //非完整数据 先存到redis，等待下一次
                redisUtils.set(code, ByteUtils.byteArrayToHexString(totalByteArray), 10, TimeUnit.SECONDS);
            }
        } else {
            logger.info("非法数据:"  + ByteUtils.byteArrayToHexString(totalByteArray));
            redisUtils.delete(code);
            return;
        }

    }


    @Async // 声明异步方法
    public void procDecode(byte[] payload,String imei){
        logger.info("开始处理数据：" + ByteUtils.byteArrayToHexString(payload));
        int byteCount = ByteUtils.byteToInt(payload[2]);
        int second = ByteUtils.byteArrayToShort(payload,3,2);
        int minute = ByteUtils.byteArrayToShort(payload,5,2);
        int hour = ByteUtils.byteArrayToShort(payload,7,2);
        int day = ByteUtils.byteArrayToShort(payload,9,2);
        int month = ByteUtils.byteArrayToShort(payload,11,2);
        int year = ByteUtils.byteArrayToShort(payload,13,2);
        StringBuilder sb = new StringBuilder();
        sb.append("时间：").append(year)
                .append("-").append(month)
                .append("-").append(day)
                .append(" ").append(hour)
                .append(":").append(minute)
                .append(":").append(second);
        logger.info(sb.toString());
        float temp = ByteUtils.byteArrayToFloatReverse(payload,15,4);
        float pressure = ByteUtils.byteArrayToFloatReverse(payload,19,4);
        float flow = ByteUtils.byteArrayToFloatReverse(payload,27,4);
        float midu = ByteUtils.byteArrayToFloatReverse(payload,31,4);
        float yacha = ByteUtils.byteArrayToFloatReverse(payload,35,4);
        float flowTotal = ByteUtils.byteArrayToFloatReverse(payload,39,4);
        sb.append("温度：").append(String.format("%.2f", temp));
        sb.append("压力：").append(String.format("%.2f", pressure));
        sb.append("瞬时流量：").append(String.format("%.2f", flow));
        sb.append("压差：").append(String.format("%.2f", yacha));
        sb.append("累计流量：").append(String.format("%.2f", flowTotal));
        logger.info(sb.toString());

        MqttDeviceCurrentDto mqttDeviceCurrentDto = new MqttDeviceCurrentDto();
        mqttDeviceCurrentDto.setTime(System.currentTimeMillis());
        mqttDeviceCurrentDto.setMethod("thing.event.property.post");
        JSONObject paramJson = new JSONObject();

        mqttDeviceCurrentDto.setDeviceCode(imei);
        paramJson.put("cumulative_flow",new BigDecimal(String.format("%.2f", flowTotal)));
        paramJson.put("pressure",new BigDecimal(String.format("%.2f", pressure)));
        paramJson.put("temp",new BigDecimal(String.format("%.2f", temp)));
        paramJson.put("flow",new BigDecimal(String.format("%.2f", flow)));
        paramJson.put("pressure_diff",new BigDecimal(String.format("%.2f", yacha)));
        mqttDeviceCurrentDto.setParams(paramJson);

       //发送消息到自己平台
        mqttSendGateway.sendToMqtt(deviceTransferService.getIotPlatPropertyTopicV1(DEVICE_TYPE) , JSONObject.toJSONString(mqttDeviceCurrentDto));
        logger.info("发送mqtt完成：TOPIC:" + deviceTransferService.getIotPlatPropertyTopicV1(DEVICE_TYPE) +"  PAYLOAD:"+ JSONObject.toJSONString(mqttDeviceCurrentDto));
    }
}
